import { defineStore } from "pinia";
import { store } from "@/store";
import { userType } from "./types";
import { routerArrays } from "@/layout/types";
import { resetRouter, router } from "@/router";
import { isArray, storageSession } from "@pureadmin/utils";
import { doLogin, doLogout, getUserInfo } from "@/api/oauth";
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";

import {
  getToken,
  removeToken,
  sessionUserKey,
  setToken,
  setUser,
  type TokenInfo,
  UserInfo,
} from "@/utils/auth";
import { GetUserInfoModel, LoginParams } from "@/api/model/oauthModel";
import { usePermissionStoreHook } from "@/store/modules/permission";
import { loadEnv } from "@build/index";
import { initRouter } from "@/router/utils";

export const useUserStore = defineStore({
  id: "pure-user",
  state: (): userType => ({
    // 用户名
    username:
      storageSession().getItem<TokenInfo<number>>(sessionUserKey)?.nickname ??
      "",
    avatar:
      storageSession().getItem<TokenInfo<number>>(sessionUserKey)?.avatar ?? "",
    // 页面级别权限
    //角色
    roles:
      storageSession().getItem<TokenInfo<number>>(sessionUserKey)?.roles ?? [],
    //权限
    permissions:
      storageSession().getItem<TokenInfo<number>>(sessionUserKey)
        ?.permissions ?? [],
  }),
  actions: {
    /** 存储用户名 */
    SET_USERNAME(username: string) {
      this.username = username;
    },
    SET_AVATAR(avatar: string) {
      this.avatar = avatar;
    },
    /** 存储角色 */
    SET_ROLES(roles: Array<string>) {
      this.roles = roles;
    },
    SET_PERMISSIONS(permissions: Array<string>) {
      this.permissions = permissions;
    },
    /** 登入 */
    async loginByUsername(data: LoginParams, to?: string) {
      return new Promise<GetUserInfoModel>((resolve, reject) => {
        doLogin(data)
          .then(res => {
            const data = {
              accessToken: res.access_token,
              expires: res.expires_in,
              refreshToken: res.refresh_token,
              cookieName: res.tokenName,
              cookieValue: res.tokenValue,
            } as TokenInfo<number>;
            setToken(data);
            this.getUserInfoAction().finally(() => {
              this.loadRouter(to);
            });
          })
          .catch(err => {
            reject(err);
          });
      });
    },
    async getUserInfoAction() {
      return new Promise<UserInfo | null>((resolve, reject) => {
        if (!getToken()) {
          resolve(null);
        }
        getUserInfo()
          .then(res => {
            const { roles = [], permissions = [], userInfo } = res;
            const user = {
              nickname: userInfo.nickName,
              avatar: userInfo.profilePicture,
              roles: isArray(roles) ? roles : [],
              permissions: isArray(permissions) ? permissions : [],
            } as UserInfo;
            setUser(user);
            resolve(user);
          })
          .catch(e => {
            reject(e);
          });
      });
    },
    /** 前端登出（不调用接口） */
    async logOut() {
      if (getToken()) {
        await doLogout(getToken().accessToken);
        this.username = "";
        this.avatar = "";
        this.roles = [];
        this.permissions = [];
        removeToken(getToken().cookieName);
        useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
        resetRouter();
      }
      await router.push("/login");
    },
    /** 刷新`token` */
    /*async handRefreshToken(data) {
      return new Promise<RefreshTokenResult>((resolve, reject) => {
        refreshTokenApi(data)
          .then(data => {
            if (data) {
              setToken(data.data);
              resolve(data);
            }
          })
          .catch(error => {
            reject(error);
          });
      });
    },*/
    async loadRouter(to?: string) {
      const { VITE_USE_DYNAMIC_ROUTER } = loadEnv();
      if (VITE_USE_DYNAMIC_ROUTER) {
        await initRouter();
      } else {
        usePermissionStoreHook().handleWholeMenus([]);
      }
      to ? await router.push(to) : await router.push("/");
    },
  },
});

export function useUserStoreHook() {
  return useUserStore(store);
}
